#ifndef PROCESS_INJECTOR_IMPL_H_
#define PROCESS_INJECTOR_IMPL_H_

#include <string>
#include <memory>
#include <Windows.h>


#include "tools/defSingleton.h"


namespace sd
{
namespace prin
{
namespace impl
{
class ProcessImpl
{
public:
	bool isStarted()const;
	void start();
    void Inject( const std::wstring&, const std::wstring& dllParams=std::wstring() );
    std::wstring getName()const;
    int getId()const;
    std::wstring getCmd()const;
private:
	friend class ProcessInjectorImpl;
	ProcessImpl( HANDLE hProcess, HANDLE hThread=NULL, bool started = true,  const std::wstring& cmdName = L"" );

	std::wstring getCallParamsName(int threadid, int processid);
	void pushCallParams(int threadid, const std::wstring& params);

	std::wstring loadName()const;
	std::wstring loadCmdName()const;
	LPTHREAD_START_ROUTINE getJumper();

	void* getLoadLibraryAddr();

	LPTHREAD_START_ROUTINE jumper_;
	HANDLE hProcess_ ;
	mutable std::wstring cmdName_;
	mutable std::wstring name_;
	HANDLE hThread_;
};


class ProcessInjectorImpl : public tools::defSingleton<ProcessInjectorImpl>
{
public:
	typedef std::auto_ptr<ProcessImpl> ProcessImplRef;
	ProcessInjectorImpl();
    ProcessImplRef createProcess(const std::wstring& name, bool start=false);
    ProcessImplRef attachToProcess( int uid );

	

private:
	typedef BOOL (*TIsWow64Process)( HANDLE hProcess, PBOOL Wow64Process);

	void checkPrivileges(){ if(!privExist_)grantPrivileges();privExist_=true; }
	void grantPrivileges();

	bool checkX6compatibility( HANDLE process );


	TIsWow64Process IsWow64Process_;
	bool privExist_;
};




}//sd
}//prin
}//impl















#endif//PROCESS_INJECTOR_IMPL_H_